home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v9n03.arc / CHKFILEC.ASM < prev    next >
Assembly Source File  |  1990-01-12  |  60KB  |  980 lines

  1.          PAGE  60,132
  2.          TITLE CHKFILEC - High performance file checker - compressed.
  3. ;        SUBTTL  General program description and use of common storage
  4. ; ----------------------------------------------------------------------------;
  5. ;        CHKFILEC - characterize files by check values, time, date and size.  ;
  6. ; ----------------------------------------------------------------------------;
  7. ;   CHKFILE 1.0 ■ PCDATA TOOLKIT Copyright (c) 1990 Ziff Communications Co.   ;
  8. ;                   PC Magazine ■ Wolfgang Stiller                            ;
  9. ;                                                                             ;
  10. ; Purpose:                                                                    ;
  11. ;        CHKFILEC will read files and then characterize them with unique      ;
  12. ;        check values, update date, update time and file size. This data      ;
  13. ;        will be written in compressed form to the report file. This          ;
  14. ;        data can be used to validate file integrity by using program         ;
  15. ;        CFcompC to compare the report files and report any changes.          ;
  16. ; ----------------------------------------------------------------------------;
  17. ;Format:                                                                      ;
  18. ;                                                                             ;
  19. ;CHKFILEC filespec1 filespec2 [/D] [/I:aa] [/T] [/1] [/2]                     ;
  20. ;                                                                             ;
  21. ;    filespec1 is the file specification for the file(s) to read. Wild cards  ;
  22. ;              such as * or ? can be used as well as a drive or directory.    ;
  23. ;    filespec2 will contain compressed report of file check data for CFcompC. ;
  24. ;    "/D"      Display directory entries as well as regular files             ;
  25. ;    "/I:aa"   Ignore files beginning with characters aa (must be 2 chars).   ;
  26. ;    "/T"      Ignored if coded. Totals are always generated.                 ;
  27. ;    "/1"      Utilizes an alternate algorithm for check value 1.             ;
  28. ;    "/2"      Utilizes an alternate algorithm for check value 2.             ;
  29. ;                                                                             ;
  30. ; ----------------------------------------------------------------------------;
  31. ;Remarks:                                                                     ;
  32. ;   CHKFILEC has been specifically designed for high speed operation using    ;
  33. ;   a minimal of resources.  It will run on any DOS PC with at least 64K      ;
  34. ;   free memory.  CHKFILEC will read all files independent of whether they    ;
  35. ;   have the hidden or the system attribute set.  CHKFILEC produces a         ;
  36. ;   report line for each file (and optionally directory) matching the         ;
  37. ;   primary file specification.  CHKFILEC will report for each file in the    ;
  38. ;   current or specified directory the following information: File status     ;
  39. ;   byte, file or directory name, check value 1, check value 2, file size,    ;
  40. ;   and the DOS date and time of last update. This information is written     ;
  41. ;   to the report file specified in filespec2.  All values are written in     ;
  42. ;   compressed (binary) form to this file.  The file status byte identifies   ;
  43. ;   the file type and whether a read or open error occurred while             ;
  44. ;   processing the file.  The filename is encrypted to make it more           ;
  45. ;   difficult to locate and modify this file.  The report file in addition    ;
  46. ;   to always containing totals of the check values, contains 32 bits of      ;
  47. ;   internal check information which makes makes the file self-checking.      ;
  48. ;   CFcompC verifies this check data and will refuse to process any report    ;
  49. ;   file which has been damaged.                                              ;
  50. ;                                                                             ;
  51. ;   If CHKFILEC encounters an error related to misuse of its parameters, it   ;
  52. ;   will produce an error message followed by a beep and a request for a      ;
  53. ;   key press.  After a key press, it will display a description of the       ;
  54. ;   correct syntax.                                                           ;
  55. ;                                                                             ;
  56. ;   Both check values utilize a very high speed algorithm for computation.    ;
  57. ;   Check value 1 is an arithmetic sum (or difference for /1) of all bytes    ;
  58. ;   in each file being checked.  Check value 2 utilizes a high speed hash     ;
  59. ;   type algorithm which utilizes circular shifts and the exclusive or        ;
  60. ;   function to generate a unique 16 value which is dependent not only on     ;
  61. ;   the value of each byte in the file, but the order of those values.  If    ;
  62. ;   /1 or /2 are specified, either or both of these algorithms can be         ;
  63. ;   changed.  This change is done at initialization time, so that the speed   ;
  64. ;   of the check value computation is not affected by these options.  The     ;
  65. ;   /1, /2 and /T options are provided mainly to make CHKFILEC compatible     ;
  66. ;   with CHKfile.                                                             ;
  67. ;                                                                             ;
  68. ; ----------------------------------------------------------------------------;
  69. ;  CHKFILEC will report for each file in the current or specified directory   ;
  70. ;  the following information:                                                 ;
  71. ;    Name of file, check values, (two 16 bit values ), the DOS time           ;
  72. ;    and date stamps of the file, and file size in hex bytes                  ;
  73. ;                                                                             ;
  74. ; Format for report (filespec2) lines:                  Field size in bytes:  ;
  75. ;File File Name +  Chk  Chk    File    Update   Update           1            ;
  76. ;Type Extension:   Val1 Val2   Size:   Date:    Time:            1            ;
  77. ;---- ------------ ---- ---- -------- -------- --------          1__________  ;
  78. ; T   filename.ext xxxx yyyy FileSize mm/dd/yy hh:mm:ss                     1 ;
  79. ; 1        1        1    1      1         1        1                        1 ;
  80. ; 1        1        1    1      1         1        1__Time of last update   2 ;
  81. ; 1        1        1    1      1         1__________ Date of last update   2 ;
  82. ; 1        1        1    1      1____________________ Size of file in bytes 4 ;
  83. ; 1        1        1    1___________________________ Check value2 for file 2 ;
  84. ; 1        1        1________________________________ Check value1 for file 2 ;
  85. ; 1        1_________________________________________ File name(encrypted) 12 ;
  86. ; 1___________________________________________________1=file 2=directory    1 ;
  87. ;  Total record length for report file (REP_REC) is 25 bytes.                 ;
  88. ;                                                                             ;
  89. ;  ** See REP_REC definition for detail on field sizes **                     ;
  90. ;                                                                             ;
  91. ; Check value 1 - Is a modified check sum or difference - 16 bits.            ;
  92. ; Check value 2 - Is a modified cumulative XOR of each character in           ;
  93. ;                 file - 16 bits.                                             ;
  94. ;                                                                             ;
  95. ; The entire report file once written is self-checking because of the         ;
  96. ; Totals record which is written out after all file check records.            ;
  97. ; The totals record contains a final 32 bits of check data which is           ;
  98. ; calculated by a different algorithm than that used by the files. This       ;
  99. ; Check data will be validated each time the report file is read.             ;
  100. ;                                                                             ;
  101. ; ----------------------------------------------------------------------------;
  102. ;  CHKFILEC will return the following DOS ERRORLEVELs:                        ;
  103. ;                                                                             ;
  104. ;  00 - Normal completion - at least one file was reported.                   ;
  105. ;  04 - No files were checked.  Either none match the filespec or all         ;
  106. ;       matched files were ignored by the /I parameter.                       ;
  107. ;  08 - Normal processing except open or I/O error detected on a file being   ;
  108. ;       checked.                                                              ;
  109. ;  32 - Open or write failed to the report output file                        ;
  110. ;  64 - (40h) Program failure due to invalid path or drive specified.         ;
  111. ; 128 - (80h) Syntax error or missing parameters on program initiation.       ;
  112. ;                                                                             ;
  113. ; ----------------------------------------------------------------------------;
  114.  
  115. ;---------------------------------------------------------------;
  116. ; Constants:                                                    ;
  117. ;---------------------------------------------------------------;
  118. BOX     EQU    254                        ;Small box character code
  119. CR      EQU    0Dh
  120. LF      EQU    0Ah
  121. CRLF    EQU    0A0Dh                      ;Carriage return line feed.
  122.  
  123. CSEG    SEGMENT
  124.         ASSUME  CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
  125. ;---------------------------------------------------------------;
  126. ; D T A description  (data transfer area):                      ;
  127. ;---------------------------------------------------------------;
  128.         ORG     80h                       ;DTA and parameter line in PSP
  129. DTA_start   DB  21 DUP (?)                ; Reserved part of DTA + parm start
  130. DTA_F_attr  DB  ?                         ; File attribtute
  131. DTA_F_time  DW  ?                         ; File time
  132. DTA_F_date  DW  ?                         ;File date
  133. DTA_FS_lowr DW  ?                         ;File size lower part
  134. DTA_FS_HIr  DW  ?                         ;File size upper part
  135. DTA_F_name  DB  13 DUP(?)                 ;File name and extension
  136.  
  137.  
  138.         SUBTTL  Main program
  139. ;******************************************************************************;
  140. ;**   Main program begins here -CHKFILEC-                                    **;
  141. ;******************************************************************************;
  142.         ORG     100h                      ; THIS IS A COM TYPE PROGRAM
  143. CHKFILEC:
  144.         CALL    Parse_parms_Print_Header  ;Parse cmdline paramters + prnt header
  145.                                           ; + find first match on file name
  146. ; ----------------------------------------------------------------------------;
  147. ; F O R M A T    F I L E    I N F O                                           ;
  148. ; Process information extracted from the directory entries (the DTA)          ;
  149. ; ----------------------------------------------------------------------------;
  150. ; GENERAL ALGORITHM:                                                          ;
  151. ; 1) Check if this is a .. or . directory or a file to ignore (/I:xx)         ;
  152. ;    If its to be ignored, go try to do another FIND NEXT generic match.      ;
  153. ; 2) Extract file name, size, date and time from the DTA.                     ;
  154. ; 3) IF its a directory, indicate by placing DIR. in the checksum field,      ;
  155. ;    otherwise the file will be opened and processed.                         ;
  156. ; ----------------------------------------------------------------------------;
  157. Format_File_Info:
  158.  
  159. ;----------------------------------------------------------------------------;
  160. ; Check if this is a file name to ignore (the .. and . directories or a file ;
  161. ; begining with xx from the "/I:xx" command line parameter).                 ;
  162. ;----------------------------------------------------------------------------;
  163.         MOV     SI, offset DTA_F_Name     ;Move FROM DTA file name field
  164.         MOV     AX,WORD PTR [SI]          ;load 1st 2 chars of this file name
  165.         CMP     AL,'.'                    ;Is it a "." or ".." directory?
  166.         JNE     Check_For_Ignore_files    ;  No, so check for ignore files
  167.         JMP     Find_Next_File            ;  Yes, it is so skip this file
  168. Check_For_Ignore_Files:
  169.         CMP     AX,Ignore_F_Name          ;Is this the file name to ignore?
  170.         JNE     Xtract_DTA_Info           ;  No, so go ahead + process this file
  171.         JMP     Find_Next_File            ;  Yes, so skip this file...
  172. ;----------------------------------------------------------------------------;
  173. ; Extract info from the DTA (data transfr area)                              ;
  174. ; Extract file name, size and update date and time.                          ;
  175. ;----------------------------------------------------------------------------;
  176. Xtract_DTA_Info:
  177.         MOV     Files_Found,'Y'           ;Indicate at least 1 file was matched!
  178.         MOV     CX,12                     ;Scan 12 characters of filename (max)
  179. ;               SI= offset DTA_F_Name     ;SI already contains loc of DTA_F_NAME
  180.         MOV     DI, offset Rep_F_Name     ;Move to output record file name
  181.  
  182. Xfer_file_name:                           ;transfer filename from DTA to Rep_rec
  183.         LODSB                             ;Load one byte from DTA for transfer
  184.         OR      AL,AL                     ;See if this=0 (end of file name)
  185.         JZ      Zero_fill                 ;If end, then zero fill rest of name
  186.         ROL     AL,1                      ;Do quick and dirty encryption
  187.         STOSB                             ;Else store char in REP_Rec file name
  188.         LOOP    Xfer_file_name            ;continue until done
  189.         JMP     Short Extract_F_Size      ;Go and format file size for output
  190.  
  191. Zero_fill:                                ;zero fill remainder of file name
  192.         MOV     AL,0
  193.         REP     STOSB                     ;Store remaining characters
  194.  
  195. ; --------------------------------------------------;
  196. ; Extract file size from DTA for display            ;
  197. ; --------------------------------------------------;
  198. Extract_F_size:                           ;Format DTA's file size for output
  199.         MOV     AX,DTA_FS_HIr             ;High portion of file size
  200.         MOV     Rep_FS_Hir,AX             ; transfer it onto report file
  201.         MOV     AX,DTA_FS_Lowr            ;lower portion of file size
  202.         MOV     Rep_FS_Lowr,AX            ; transfer it onto report file
  203. ; --------------------------------------------------;
  204. ; Extract file date from DTA for display            ;
  205. ; --------------------------------------------------;
  206.         MOV     AX,DTA_F_date             ;Date of last file update
  207.         MOV     Rep_F_Date,AX             ;  Transfer file date to report file
  208. ;       date is in yyyyyyym mmmddddd format (year is offset from 1980)
  209. ; --------------------------------------------------;
  210. ; Extract file time from DTA for display            ;
  211. ; --------------------------------------------------;
  212.         MOV     AX,DTA_F_time             ;time of last file update
  213. ;       time is in hhhhhmmm mmmsssss format (seconds are 0-29 in 2 sec intervl)
  214.         MOV     Rep_F_Time,AX             ;  transfer to the report file
  215.  
  216. ; Check if this file is a directory entry rather than a file
  217.         TEST    DTA_F_attr,00010000B      ;Check directory bit of file attribute
  218.         JZ      Open_the_File             ;If not continue with normal process
  219.  
  220. ; Do special handling for directory entries (rather than file entries):
  221.         MOV     Rep_F_Type,2              ;2 means this is a directory
  222. Finish_with_Zero_Check_Vals:              ;Termnate with zeros in chk val fields
  223.         MOV     Rep_CHK_Sum,0             ;Zero the check value 1 on report file
  224.         MOV     Rep_XOR_Sum,0             ;Zero the check value 2 (XOR sum)
  225.         JMP     Write_Rep_Rec             ;Skip rest of processing and go write
  226.                                           ;   this dir entry + find next file
  227. ; --------------;
  228. ; Open the file ;
  229. ; --------------;
  230. Open_the_File:
  231.         MOV     Rep_F_Type,1              ;1 means this is a file not a dirctry
  232.  
  233.         MOV     DX,offset DTA_F_name      ;point to file name in DTA
  234.         MOV     AX,3D00h                  ;DOS open file (handle) for read cmnd
  235.         INT     21h                       ;invoke DOS
  236.         JNC     Continue_Open             ;If no errors continue processing
  237.                                           ;  a report that open failed
  238. ; This open should never fail...(OS2 can have files open which will cause fail)
  239.         MOV     File_Error_Flag,'Y'       ;Indicate that file had serious error
  240.         MOV     Rep_F_Type,3              ;3 means open fail on THIS file
  241.         JMP     SHORT Finish_with_Zero_Check_Vals  ;No valid CHK vals avail
  242.  
  243. Continue_Open:
  244.         MOV     BX,AX                     ;Save file handle
  245.         XOR     BP,BP                     ;zero out (clear) EOF indicator
  246. ; -------------------------------------------;
  247. ; Initialize check values for each file.     ;
  248. ; -------------------------------------------;
  249.         MOV     DI,BP                     ;Zero check sum (check val 1)
  250.         MOV     DX,BP                     ;Zero XOR sum (check value 2)
  251.  
  252.  
  253. ; ----------------------------------------------------------------;
  254. ; START OF LOOP TO READ AND SCAN RECORDS                          ;
  255. ; ----------------------------------------------------------------;
  256. ; REGISTER USAGE CONVENTIONS IN READ_FILE LOOP:                   ;
  257. ;                                                                 ;
  258. ; AL - Each new character read into this register                 ;
  259. ; BP - EOF (End Of File) indicator (flag)                         ;
  260. ; BX - Contains current file handle                               ;
  261. ; CX - number of chars read in -decreasing counter                ;
  262. ; DI - Contains check value 1 for this file (CHKSUM)              ;
  263. ; DX - Check value 2 for file and periodically start of buffer    ;
  264. ; SI - index pointing into file BUFFER                            ;
  265. ; ----------------------------------------------------------------;
  266. Read_File:
  267.         PUSH    DX                        ;Save the XOR sum (check value 2)
  268.         MOV     DX,OFFSET Buffer          ;INPUT BUFFER
  269.         MOV     SI,DX                     ;SI is for BUFFER reads later
  270.         MOV     CX,0FC00h                 ;MAX # of bytes to read
  271.         MOV     AH,3Fh                    ;Setup to read from file
  272.         INT     21h                       ;Call DOS
  273.         POP     DX                        ;Resume using DX for check val 2
  274.         JNC     Read_was_OK               ;IF neither error nor EOF occurred.
  275.         MOV     File_Error_Flag,'Y'       ;      No, we've got a read error
  276.         MOV     Rep_F_Type,4              ;        4 means read error
  277.         JMP     SHORT Done_reading        ;        Write out this REP_REC
  278. Read_was_OK:
  279.         OR      AX,AX                     ;Check if ax=0 no records read
  280.         JZ      Done_reading              ;If no records, close this file..
  281.         CMP     AX,CX                     ;See of max number or records read
  282.         JE      Skip_EOF_ind              ;If we have compltly filled buffer
  283.         MOV     BP,SP                     ;  Else put EOF indicator in BP
  284. Skip_EOF_ind:                             ;Jump here to skip setting EOF
  285.         MOV     CX,AX                     ;SAVE # of BYTES read in CX
  286.         JCXZ    Done_reading              ;Quit if nothing read
  287.         XOR     AH,AH                     ;Zero upper part of AX for addition
  288.  
  289. ; Innermost read char loop  - keep this fast!
  290. NEXT_CHAR:
  291.         LODSB                             ;Get char into AL
  292.         XOR     DL,AL                     ;cumulative XOR into DX - Chck val 2
  293.                                           ;following instr modified by /2 parm
  294. ROL_op: ROL     DX,1                      ;Keep shifting to XOR sum to right
  295.                                           ;following instr modified by /1 parm
  296. ADD_op: ADD     DI,AX                     ;cumulative check sum - Chck val 1
  297.         LOOP    NEXT_CHAR                 ;CONTINUE SCANNING CHARS UNTIL EOB
  298.  
  299.         OR      BP,BP                     ;Check EOF indicator (=77h if EOF)
  300.         JNZ     Done_reading              ;IF EOF, quit this file...
  301.         JMP     SHORT Read_File           ;TRY TO READ SOME MORE
  302.  
  303. Done_reading:                             ;Come here on EOF or error reading
  304.         MOV     AH,3Eh                    ;Prepare to close the file
  305.         INT     21h                       ;Let DOS close file
  306.         MOV     Rep_CHK_Sum,DI            ;Put check sum (chk val 1) in rep rec
  307.         MOV     Rep_XOR_Sum,DX            ;Do same with XOR sum (check val 2)
  308.         ADD     Tot_CHK_Sum,DI            ;Total check value 1 for all files
  309.         ADD     Tot_XOR_Sum,DX            ;Total check value 2 for all files
  310.  
  311. ;---------------;
  312. ; Write Rep_REC ;
  313. ;---------------;
  314. Write_Rep_Rec:
  315.         MOV     DX, offset Rep_rec        ;prepare to write output record
  316.         MOV     CX,25                     ;25 chars in Rep_rec
  317.         MOV     BX,Filespec2_Handle       ;Handle for std output device
  318.         MOV     AH,40h                    ;DOS Write function
  319.         INT     21h
  320.         JNC     Calc_Global_CHK_data      ;If write was OK, then continue
  321.         JMP     Report_Write_Error        ;Else notify user of fatal error
  322.  
  323. ;-----------------------------------------------------------------------;
  324. ; CALC GLOBAL CHECK DATA - Calculate global checksum and XOR values for ;
  325. ;        the report file. This information allows the report file to be ;
  326. ;        self checking. Any change to it can then be detected.          ;
  327. ;**Note, this algorithm is different than that used for file checking** ;
  328. ;-----------------------------------------------------------------------;
  329. Calc_Global_CHK_Data:
  330.         MOV     SI,DX                     ;Get start of buffer to calc chk data
  331.                                           ;CX should still contain 25 (rec len)
  332.         MOV     DX,Rep_Rec_XORval         ;Pick up cumulative XOR from before
  333.         MOV     BX,Rep_Rec_CHKsum         ;Get last CHKsum(for entire rep file)
  334.         CALL    Calc_Sums                 ;Accumulate check values for this rec
  335.         MOV     Rep_Rec_XORval,DX         ;Save cumulative XOR value
  336.         MOV     Rep_Rec_CHKsum,BX         ;Save cumulative CHKsum
  337.  
  338.  
  339. ;-------------------------------;
  340. ; Search for next matching file ;
  341. ;-------------------------------;
  342. Find_Next_File:
  343.         MOV     AH,4Fh                    ;Search for next matching file
  344.         INT     21h                       ;Do search
  345.         JC      Finish_Processing         ;If no more matches, terminate.
  346.         JMP     Format_File_Info          ;If no errors, process this file
  347.  
  348. Finish_Processing:                        ;Else, Prepare to terminate
  349.  
  350. ;If no files matched the filespec1 and were not ignored (/I:__) then just
  351. ;write a one byte zero record to indicate no matches.
  352.         CMP     Files_Found,'Y'           ;Were any files at all checked?
  353.         JE      Write_Totals_record       ;  If so, write out totals record
  354.         JMP     No_Files_Matched          ;  Else just write zero record
  355.  
  356. Write_Totals_Record:
  357. ; Move cumulative file totals into Rep_REC for display
  358.         MOV     DI,Tot_CHK_Sum            ;Prepare cumulative totals for dsply
  359.         MOV     DX,Tot_XOR_Sum
  360.         MOV     Rep_CHK_Sum,DI            ;Xfer to coorespnding report fields
  361.         MOV     Rep_XOR_Sum,DX
  362. ; Now save check data for this entire report file as the last 4 bytes:
  363.         MOV     DX,Rep_Rec_XORval        ;Pick up cumulative XOR val
  364.         MOV     BX,Rep_Rec_CHKsum        ;Get cumulative CHKsum value
  365.         MOV     Rep_FS_Lowr,DX           ;Save XOR on file
  366.         MOV     Rep_FS_HIr,BX            ;Save CHKsum
  367.  
  368.  
  369.  
  370. ; Write the cumulative file totals and check data line
  371.         MOV     DX, offset Rep_CHK_SUM    ;Write totals rec (only chk+Xor sums)
  372.         MOV     AH,40h                    ;Write function
  373.         MOV     BX,Filespec2_Handle       ;Report file handle
  374.         MOV     CX,8                      ;Write only first 8 chars
  375.         INT     21h                       ;Actually write out the totals line
  376.         JNC     Check_drive_path_changes  ;If write, was OK
  377.  
  378. Report_Write_Error:
  379.         MOV     DX, OFFSET Write_fail_Msg ;tell user of I/O error
  380.         MOV     AH,09h                    ;DOS display string function
  381.         INT     21h
  382.  
  383. ;-----------------------------------------------------------------------;
  384. ; NORMAL TERMINATION starts here. All termination conditions where at   ;
  385. ;        least some records were matched begin here.                    ;
  386. ;-----------------------------------------------------------------------;
  387. ;   1) Restore user back to his original drive and path (if changed)    ;
  388. ;   2) Close the report file                                            ;
  389. ;   3) Set error level of 8 if we had file IO or open problems          ;
  390. ;   4) Terminate with errorlevel of 0 (all is OK) or 8                  ;
  391. ;-----------------------------------------------------------------------;
  392.  
  393. Check_drive_path_changes:
  394.         Call    Restore_Original_Path     ;Set back to original path if changd
  395.         Call    Restore_Original_Drive    ;Set back to original drive if changd
  396.  
  397.         MOV     BX,Filespec2_handle       ;Prepare to close the report file
  398.         MOV     AH,3Eh                    ;DOS Close function
  399.         INT     21h
  400.  
  401.         MOV     AL,00h                    ;Plan on termination with 0 errlvl
  402.         CMP     File_Error_Flag,'Y'       ;Did we get a file I/O error ?
  403.         JNE     End_Execution             ;  If not, term with 0 error level
  404.         MOV     AL,08h                    ;  Else, terminate with 8 error level
  405.  
  406. End_Execution:                            ;Successful termination of program
  407.         MOV     AH,4Ch                    ;terminate with error level in AL
  408.         INT     21h
  409.  
  410.         SUBTTL  General Purpose subroutines
  411.         PAGE
  412. ;******************************************************************************;
  413. ;**   General purpose subroutines follow                                     **;
  414. ;******************************************************************************;
  415.  
  416. ;------------------------------------------------------------------------------;
  417. ;   Restore orginal drive - if disk changed, set back to original disk.        ;
  418. ;------------------------------------------------------------------------------;
  419. Restore_Original_Drive:                   ;Set back to original drive if changd
  420.         CMP     Drive_Spec_Present,'Y'    ;Did user overide drive?
  421.         JNE     Restore_Drive_RET         ;If not then return to caller
  422.         MOV     DL,Old_disk               ;get original drive
  423.         MOV     AH,0Eh                    ;Set current drive function
  424.         INT     21h
  425. Restore_Drive_RET:
  426.         RET
  427.  
  428. ;------------------------------------------------------------------------------;
  429. ;   Restore orginal path - if path changed, set back to original disk.         ;
  430. ;------------------------------------------------------------------------------;
  431. Restore_Original_Path:                    ;Set back to orignl path if changed
  432.         CMP     Path_Present,'Y'          ;Did user overide path (Directory)
  433.         JNE     Restore_Path_RET          ;If not, return to caller
  434.         MOV     AH,3Bh                    ;Change current directory function
  435.         MOV     DX,offset Old_path        ;Original path
  436.         INT     21h                       ;Set path back to original
  437. Restore_Path_RET:
  438.         RET
  439.  
  440. ;---------------------------------------------------;
  441. ; C A L C _  S U M S -  Calculate check values      ;
  442. ;---------------------------------------------------;
  443. ; This is a special version for CFcompC + CHKFILEC. ;
  444. ;---------------------------------------------------;
  445. ; INPUT:  SI = pointer to file BUFFER to scan       ;
  446. ;         CX = # of characters to read              ;
  447. ;         DX = cumulative XOR sum  - check value 1  ;
  448. ;         BX = cumulative CHK sum  - check value 2  ;
  449. ;                                                   ;
  450. ;Register conventions:                              ;
  451. ;                                                   ;
  452. ; AL - Each new character read into this register   ;
  453. ; CX - number of chars read in -decreasing counter  ;
  454. ; BX - Contains checksum for this file              ;
  455. ; DX - XOR check value                              ;
  456. ; SI - index pointing into file BUFFER              ;
  457. ;                                                   ;
  458. ; None of above registers are saved and restored.   ;
  459. ; --------------------------------------------------;
  460. Calc_Sums:
  461.         XOR     AH,AH                     ;Zero upper part of AX for addition
  462. Grab_next_char:
  463.         LODSB                             ;Get char into AL
  464.         ROR     DX,1                      ;Keep shifting to XOR sum to left
  465.         XOR     DL,AL                     ;cumulative XOR into DX
  466.         SUB     BX,AX                     ;cumulative check subtraction
  467.         LOOP    Grab_Next_Char            ;CONTINUE SCANNING CHARS UNTIL EOB
  468.         RET                               ;All done calculating sums!
  469.  
  470.  
  471.         SUBTTL  Definition of Data structures
  472.         PAGE
  473. ;******************************************************************************;
  474. ;**   Definition of Data areas follow                                        **;
  475. ;******************************************************************************;
  476. File_Error_Flag   DB  'N'                 ;='Y' indicates file IO or open error
  477.  
  478. ;Report file record description:
  479. Rep_Rec           EQU  $                  ;Name for the entire output record
  480. Rep_F_Type        DB   0                  ;Indicates if its a file (1) or dir(2)
  481.                                           ;or file with open err(3) or IO err(4)
  482. Rep_F_Name        DB   12 DUP (0)         ;12 spaces reserved for filename
  483. Rep_CHK_Sum       DW   0                  ;Check sum: 16 bits
  484. Rep_XOR_Sum       DW   0                  ;Exclusive OR sum
  485. Rep_FS_Lowr       DW   0                  ;File size lower part of double word
  486. Rep_FS_HIr        DW   0                  ;File size: upper part of double word
  487. Rep_F_Date        DW   0                  ;Date of last file update:
  488. Rep_F_Time        DW   0                  ;Time of last file update
  489.  
  490. Rep_Rec_XORval    DW   0                  ;Global cumulative XOR value(rep rec)
  491. Rep_Rec_CHKsum    DW   0                  ;Global cumulative CHK value(rep rec)
  492.  
  493. Old_Path          DB   '\'                ;Force 1st char of save area to = '\'
  494.                   DB   64 DUP (0)         ;Save area to restore original path
  495. Old_Disk          DB   0                  ;Save area for original drive spec
  496. Drive_Spec_Present DB  0                  ;Set = to "Y" if drive spec present
  497. Path_Present      DB   0                  ;Set = to "Y" if path specified
  498. Tot_CHK_Sum       DW   0                  ;total of all check sums (all files)
  499. Tot_XOR_Sum       DW   0                  ;total of exclusive or sums
  500. Ignore_F_Name     DW   '  '               ;ignore file names starting with this
  501. Filespec2_handle  DW   0                  ;Handle for the report file
  502. Files_Found       DB   'N'                ;Indicates in any files matched:Y or N
  503. Write_fail_Msg    DB   'File2 write failed',CR,LF,'$'
  504.         SUBTTL  INIT data and code which is also input BUFFER
  505.         PAGE
  506. ;******************************************************************************;
  507. ;**   Definition of file buffer Data areas and code follow:                  **;
  508. ;** All the following storage will be overlaid when records are read in      **;
  509. ;******************************************************************************;
  510.  
  511. Buffer        label  byte                 ;All storage + code following is in
  512.                                           ; the input file buffer.
  513.                                           ; address must be less than 3F0 hex.
  514.  
  515. ; ----------------------------------------------------------------------------;
  516. ; Initialization code - parse parms + put out msgs and find intial file match ;
  517. ; ----------------------------------------------------------------------------;
  518. Parse_parms_Print_Header:                 ;Parse input parameters + print header
  519.         MOV     SI,80h                    ;Parameter area in PSP
  520.         MOV     CL,[SI]                   ;Get # of chars in input parm
  521.         XOR     CH,CH                     ;Clear upper byte of char count
  522.         OR      CL,CL                     ;Check for 0 chars (NO INPUT)
  523.         MOV     BP,128                    ;Error level code for syntax error
  524.         JZ      Display_Syntax_Msg        ;IF no parms, put out help information
  525.         INC     SI                        ;Point to 1st character
  526.         CLD                               ;FORWARD DIRECTION
  527.  
  528. Del_Spaces:
  529.         LODSB                             ;Get byte at DS:SI and inc SI
  530.         CMP     AL,' '                    ;Is it a space?
  531.         JNE     Set_File_names            ;If not we have a file name..
  532.         LOOP    Del_Spaces                ;continue checking until last char
  533.         MOV     BP,128                    ;Error level code for syntax error
  534.         JMP     SHORT Display_Syntax_Msg  ;Explain syntax to user
  535. Syntax_Err_Exit:                          ;Come here on syntax error
  536.         MOV     AH,09h                    ;DOS display string function
  537.         INT     21h
  538.         CALL    Wait_For_Key              ;Beep + force user to hit a key{
  539. Display_Syntax_Msg:
  540.         MOV     DX, OFFSET Syntax_Msg     ;Prepare ERROR Message
  541.         MOV     AH,09h                    ;DOS display string function
  542.         INT     21h
  543.         Call    Restore_Original_Drive    ;Set back to original drive if changd
  544.         MOV     AX,BP                     ;Get error level in AL from lower BP
  545.         MOV     AH,4Ch                    ;   terminate with errorlevel in AL
  546.         INT     21h
  547.  
  548. ;---------------------------------------------------------------------------;
  549. ; Conventions for command line parsing:                                     ;
  550. ;   SI points to next char to be checked in the parm field at DS:80         ;
  551. ;   CX is count of characters left to be scanned                            ;
  552. ;   BP points to start of filespec1 for find next processing                ;
  553. ;---------------------------------------------------------------------------;
  554.  
  555. ;----------------------------------------;
  556. ; Parse filespec1 and xfer in msg field  ;
  557. ;----------------------------------------;
  558. Set_File_Names:
  559.         CMP     BYTE PTR [SI],':'         ;Check for presence of drive spec
  560.         JNZ     Read_file_spec
  561.         AND     AL,5Fh                    ;Capitalize drive letter
  562.         SUB     AL,'A'                    ;Convert to numeric form
  563.         MOV     New_Drive,AL              ;Save num drive - change to it later
  564.         MOV     Drive_spec_present,'Y'    ;Indicate user is overriding drive
  565.         MOV     AH,19h                    ;DOS get current drive function
  566.         INT     21h
  567.         MOV     Old_disk,AL               ;Save current disk
  568.  
  569.         ADD     SI,2                      ;adjust pointers and
  570.         SUB     CX,2                      ;      counters to skip drive spec
  571.  
  572. Read_file_spec:
  573.         DEC     SI                        ;point back to 1ST letter of filespec
  574.         MOV     BP,SI                     ;Save a copy of filespec start
  575.         MOV     DI, offset User_File_Spec ;prep to transfer file name to msg
  576.  
  577. Scan_To_File_Spec_End:
  578. ;       start scanning the file specification and transfer into output field
  579.         LODSB                             ;Get next char of file spec
  580.         CMP     AL,' '                    ;check valid separator character
  581.         JBE     File_Spec_End_Found
  582.         CMP     AL,' '                    ;check valid separator character
  583.         JE      File_Spec_End_Found
  584.         STOSB                             ;Store char as part of User_file_spec
  585.         LOOP    Scan_To_File_Spec_End
  586.         INC     SI                        ;Adjust BX if no separator char found
  587.  
  588. File_Spec_End_Found:
  589.         MOV     BX,SI
  590.         DEC     BX                        ;= next char loc after filespec
  591.         MOV     BYTE PTR [BX],00          ;zero terminate the filespec: ASCIIZ
  592.         PUSH    AX                        ;Save last char examined
  593.         MOV     AX,CRLF                   ;Put out carriage return line feed
  594.         STOSW                             ;  combination as a single word
  595.         MOV     AL,LF                     ;Include extra line feed
  596.         STOSB
  597.         POP     AX                        ;Restore last character examined
  598.  
  599. ;---------------------------------------------------------------------------;
  600. ; Parse filespec2:  (Not a called subroutine - just a code module)          ;
  601. ; Input:                                                                    ;
  602. ;   SI points to next char to be checked in the parm field at DS:80         ;
  603. ;   CX is count of characters left to be scanned                            ;
  604. ;                                                                           ;
  605. ; Returns:                                                                  ;
  606. ;   DI points to byte after last char in filespec                           ;
  607. ;   Filespec is zero terminated in the parameter area                       ;
  608. ;---------------------------------------------------------------------------;
  609. Parse_Filespec2:                          ;Extract and zero terminate filename
  610.         OR      CL,CL                     ;Check for 0 chars (NO INPUT)
  611.         JZ      Bad_filespec2             ;If no parms, display error message
  612. Del_Spaces2:
  613.         LODSB                             ;Get byte at DS:SI and inc SI
  614.         CMP     AL,' '                    ;Is it a space?
  615.         JNE     Get_Filespec2             ;If not, we should have a file name..
  616.         LOOP    Del_Spaces2               ;Continue checking until last char
  617. Bad_Filespec2:
  618.         MOV     DX, OFFSET Bad_file2_Msg  ;tell user filespec2 is needed
  619.         MOV     BP,32                     ;Terminate with 32 (20h) err lvl
  620.         JMP     Syntax_Err_Exit           ;Display error msg + correct syntax
  621.  
  622. ;--------------------------------------------;
  623. ; Parse file spec and zero byte terminate it ;
  624. ;--------------------------------------------;
  625. Get_Filespec2:
  626.         DEC     SI                        ;point back to 1ST letter of filespec
  627.         MOV     File2_Start,SI            ;Save a copy of filespec2 start
  628.  
  629. Scan_to_filespec2_end:
  630. ;       start scanning the file specification and transfer into output field
  631.         LODSB                             ;Get next char of file spec
  632.         CMP     AL,' '                    ;Check valid separator character
  633.         JBE     Filespec2_End_Found
  634.         CMP     AL,'/'                    ;Check for valid separator
  635.         JE      Filespec2_End_Found
  636.         CMP     AL,','                    ;Check for valid separator
  637.         JE      Filespec2_End_Found
  638.         LOOP    Scan_to_filespec2_end
  639.         INC     SI                        ;Adjust SI if no separator char found
  640.  
  641. Filespec2_end_found:
  642.         DEC     CX                        ;Correct the char remaining count
  643. ;       SI is pointing 2 characters past end of filespec at this time
  644.         MOV     DI,SI
  645.         DEC     DI                        ;DI points to 1st char after filespec2
  646.         MOV     BYTE PTR [DI],00          ;zero terminate filespec2: ASCIIZ
  647.  
  648. ;---------------------------------------------------;
  649. ;Check parameter characters left.                   ;
  650. ;At this point we begin the scan for the /x type    ;
  651. ;Parameters. (if any).                              ;
  652. ;---------------------------------------------------;
  653. Check_parm_chars_left:                    ;Check if enough chars left for a parm
  654.         CMP     CX,01                     ;Check if we out of chars to scan
  655.         JA      Parm_Scan                 ;  if not continue chcking for /parms
  656.         JMP     Open_Filespec2            ;  If so, cont with next step of init
  657. Parm_Scan:                                ;Check for presence of a /_ parm
  658.         CMP     AL,'/'                    ;check for "/" parm character
  659.         JE      Parm_found
  660.         CMP     AL,' '                    ;check for blanks
  661.         JNE     Unrecog_parm              ;If other than blank its illegal...
  662.         LODSB                             ;Keep checking next character
  663.         LOOP    Parm_Scan
  664.         JMP     short Open_Filespec2      ;Continue with initialization...
  665.  
  666. Parm_Found:                               ;Check if parm is valid
  667.         DEC     CX                        ;Adjust chars remaining counter
  668.         JCXZ    Unrecog_parm              ;IF no chars left then parm is invalid
  669.         LODSB                             ;Get next char
  670.         DEC     CX                        ;Adjust chars remaining counter
  671.         CMP     AL,'2'                    ;Is it alternate chk val 2 (XOR) parm?
  672.         JE      X2_parm                   ;exclusive or parm detected (/2)
  673.         CMP     AL,'1'                    ;Is it alternate Chk val 1 (Sum) parm?
  674.         JE      C1_parm                   ;/1 parameter detected..
  675.         AND     AL,5Fh                    ;Capitalize char
  676.         CMP     AL,'T'                    ;Is it the "Totals wanted" parm?
  677.         JE      T_parm                    ;T parameter detected
  678.         CMP     AL,'D'                    ;Is it Directory display parm?
  679.         JE      D_parm                    ;D parameter detected..
  680.         CMP     AL,'I'                    ;Is it Ignore file parm?
  681.         JE      I_parm                    ;I parameter detected.. else its...
  682. Unrecog_parm:                             ; an illegal paramter:
  683.         MOV     DX, offset Bad_Parm_MSG   ;indicate illegal parm was found
  684.         MOV     BP,128                    ;Error level code for syntax error
  685.         JMP     Syntax_ERR_Exit                  ;terminate with error level set
  686.  
  687. ;T parm is maintained for compatibility with CHKFILE only...it is ignored
  688. T_parm:                                   ;This parameter has no effect
  689.         LODSB                             ;Keep checking next character
  690.         JMP     SHORT Check_Parm_chars_left     ;Check for additional parms
  691.  
  692. X2_parm:
  693.         MOV     WORD PTR [ROL_op],0CAD1h  ;patch ROL op code into ROR DX,1 op
  694.         LODSB                             ;Keep checking next character
  695.         JMP     SHORT Check_Parm_chars_left     ;Check for additional parms
  696.  
  697. C1_parm:                                  ;Use of alt CHK sum algor(/1 parm)
  698.         MOV     WORD PTR [ADD_op],0C729h  ;patch ADD op code into SUB DI,AX op
  699.         LODSB                             ;Keep checking next character
  700.         JMP     SHORT Check_Parm_chars_left     ;Check for additional parms
  701.  
  702. D_parm:
  703.         MOV     WORD PTR [File_Attrib],0017h ;Change file attrib to incl DIRs
  704.         LODSB                                ;Keep checking next character
  705.         JMP     SHORT Check_Parm_chars_left  ;Check for additional parms
  706.  
  707. I_parm:
  708.         CMP     CX,03                     ;We must have at least 3 chars left
  709.         JB      Unrecog_parm              ;If not, this is a bad parameter
  710.         LODSB                             ;Check next character
  711.         CMP     AL,':'                    ;  it should be ':'
  712.         JNE     Unrecog_parm              ;If not, its bad parm time again..
  713.         SUB     CX,03                     ;Adjust chrs remaining counter
  714.         LODSW                             ;Get file prefix to ignore
  715.  
  716. ;     Now capitalize the file name prefix, only if lower case alphabetic
  717.         CMP     AL,'a'                    ;could this be a lower case alpha?
  718.         JB      Check_2nd_char            ;If not go ahead and check other char
  719.         CMP     AL,'z'                    ;could this be a lower case alpha?
  720.         JA      Check_2nd_char            ;If not go ahead and check 2nd char
  721.         AND     AL,5Fh                    ;Bump character into uppercase
  722. Check_2nd_char:                           ;Now check the 2nd file ignore char
  723.         CMP     AH,'a'                    ;could this be a lower case alpha?
  724.         JB      I_store                   ;If not go ahead and store the char
  725.         CMP     AH,'z'                    ;could this be a lower case alpha?
  726.         JA      I_store                   ;If not go ahead and store the char
  727.         AND     AH,5Fh                    ;Bump character into uppercase
  728.  
  729. I_store:
  730.         MOV     Ignore_F_Name,AX          ;Store file prefix (for ignore)
  731.         LODSB                             ;Keep checking next character
  732.         JMP     Check_Parm_chars_left     ;Check for additional parms
  733.  
  734. Invalid_path:
  735.         MOV     DX,offset Bad_path_MSG    ;Indicate problem with path
  736.         MOV     BP,64                     ;Errorlevel for bad drive or path
  737.         JMP     Syntax_Err_Exit           ;Report error+displ correct syntax
  738.  
  739. ;--------------------------------------;
  740. ;   Open the report file (filespec2):  ;
  741. ;--------------------------------------;
  742. Open_Filespec2:
  743.         MOV     DX,File2_Start            ;DX contains filespec2 start
  744.         MOV     AH,3Ch                    ;DOS create and truncate file func
  745.         XOR     CX,CX                     ;Set CX=0, means normal file attrib
  746.         INT     21h                       ;invoke DOS
  747.         JNC     Filespec2_Open_OK         ;If no errors continue processing
  748.         MOV     DX, OFFSET F2_open_fail   ;tell user filespec2 open failed
  749.         MOV     BP,32                     ;   terminate with 32 error level
  750.         JMP     Syntax_Err_Exit           ;Display error followed by syntax
  751. Filespec2_Open_Ok:
  752.         MOV     Filespec2_handle,AX       ;Save the file handle
  753.  
  754. ;--------------------------------------------------------------;
  755. ; Set system default disk drive to that specified in filespec1 ;
  756. ;--------------------------------------------------------------;
  757. Set_Filespec1_New_Drive:
  758.         CMP     Drive_spec_present,'Y'    ;Did user override drive spec?
  759.         JNE     Check_for_DIR             ;  No, then we don't need to change it
  760.         MOV     DL,New_Drive              ;  Else get numeric drive spec + chng
  761.         MOV     AH,0Eh                    ;    DOS select disk function
  762.         INT     21h                       ;    Set to drive in filespec1
  763.         JNC     Check_For_DIR             ;    Was the disk drive specified OK?
  764.         JMP     Invalid_Path              ;    If drive specified is invalid..
  765.  
  766. Check_for_DIR:                            ;See if PATH included in filespec1
  767.         MOV     CX,BX                     ;End of filespec1 + 1
  768.         SUB     CX,BP                     ;Calc length of filespec1
  769.         PUSH    CX                        ;Save length for use later
  770.         STD                               ;Prepare to scan filespec1 backwards
  771.         MOV     DI,BX                     ;Start from end
  772.         DEC     DI                        ;                of filespec1
  773.         MOV     AL,'\'                    ;Scan filespec1 for presence of "\"
  774.         REPNE   SCASB                     ;Scan to last \ from end of filespec1
  775.         CLD                               ;Reset direction flag to forward
  776.         JNZ     Display_Heading           ;IF, no path found in filespec1
  777.         MOV     Path_Present,'Y'          ;Set flag to indicate path present
  778.         INC     DI                        ;Point to "\" character
  779.         MOV     BYTE PTR [DI],0           ;Zero terminate the PATH (clobber \)
  780.                                           ;Determine current directory
  781.         MOV     SI,offset Old_path+1      ;Place to store original directory
  782.         XOR     DL,DL                     ;Zero DL in order to use default drive
  783.         MOV     AH,47h                    ;Get current directory (path) func
  784.         INT     21h
  785.         JC      Invalid_path              ;IF function failed(will never happen)
  786. ; prepare to set to user's specified file path (directory)
  787.         MOV     DX,BP                     ;Begining of dir in parm area
  788.         CMP     DI,BP                     ;Is \ 1st + only compnnt of dir stng?
  789.         JNE     Not_Root_Dir              ;If \ is only char, this is root dir
  790.         MOV     DX, offset Root_Dir       ;  so set directory to root directory
  791. Not_Root_Dir:
  792.         MOV     AH,3Bh                    ;Set current directory function
  793.         INT     21h
  794.         JC      Invalid_path              ;IF function failed
  795.         INC     DI                        ;Point to start of filename1 (path+1)
  796.         MOV     BP,DI                     ;Set new filename start (skip path)
  797.  
  798. ;----------------------------------------------------------------------------;
  799. ; Display the start message and the heading for the file list                ;
  800. ;----------------------------------------------------------------------------;
  801. Display_Heading:
  802.         MOV     DX,OFFSET Start_MSG       ;Put out main banner msg for output
  803.         MOV     AH,40h                    ;DOS DISPLAY STRING FUNCTION
  804.         MOV     CX,SM_End-Start_MSG       ;# of chars in start msg
  805.         MOV     BX,1                      ;Handle for std output device
  806.         INT     21h
  807.         MOV     DX,OFFSET User_File_Spec  ;Tell user what files we're checking
  808.         MOV     AH,40h                    ;DOS write file funct (std output)
  809.         POP     CX                        ;Get length of filespec1
  810.         ADD     CX,3                      ;add extra chars to length (CRLF LF)
  811.         INT     21h
  812.  
  813. ;----------------------------------------------------------------------------;
  814. ; Find first occurance of a file to match the possible wildcards in filespec1;
  815. ;----------------------------------------------------------------------------;
  816. Find_First_File:
  817.         MOV     DX,BP                     ;DX points to filename of filespec1
  818.         MOV     AH,4Eh                    ;DOS find first command (use 80H DTA)
  819.         MOV     CX,File_attrib            ;Set file attrib
  820.         INT     21h                       ;Invoke DOS
  821.         JNC     Done_FFF                  ;If no carry, then all is OK..
  822.  
  823. No_Files_Matched:                         ;Come here when no files checked
  824.         Call    Restore_Original_Path     ;Set back to original path if changd
  825.         Call    Restore_Original_Drive    ;Set back to original drive if changd
  826.  
  827. ; Report that no files were matched to the user
  828.         MOV     DX, OFFSET No_CHK_Msg     ;Tell users no files matched
  829.         MOV     AH,09h                    ;DOS display string function
  830.         INT     21h
  831. ; Write 1 byte record indicating no files matched
  832.         MOV     AH,40h                    ;DOS write file function
  833.         MOV     BX,Filespec2_handle       ;Report file, file handle
  834.         MOV     CX,1                      ;Write 1 byte zero record
  835.         MOV     DX,OFFSET Zero_Byte       ;single hex zero to write
  836.         INT     21h                       ;Write 1 byte of zero to report file
  837.         JNC     ClOSE_Report_File         ;If write was OK, close file + finish
  838.         JMP     Report_Write_Error        ;Notify user of fatal write error
  839.  
  840. Close_Report_File:
  841.         MOV     AH,3Eh                    ;DOS Close function
  842.         INT     21h                       ;Close the report file
  843.         MOV     AX,4C04h                  ;   terminate with 04 error level
  844.         INT     21h
  845.  
  846. Done_FFF:
  847.         RET
  848.  
  849. ;---------------------------------------------------;
  850. ; W A I T   F O R   K E Y                           ;
  851. ;---------------------------------------------------;
  852. ; 1) Send out a BEEP                                ;
  853. ; 2) Determine screen attribute (screen colors)     ;
  854. ; 3) Determine what line cursor is on               ;
  855. ; 4) Put out message to hit any key on that line    ;
  856. ; 5) Wait for any keypress                          ;
  857. ; 6) Erase message using current screen attribute   ;
  858. ; 7) Position currsor back at start of current line.;
  859. ; --------------------------------------------------;
  860. ; ***  ALL REGISTERS MAY BE CORRUPTED EXCEPT BP *** ;
  861. ; --------------------------------------------------;
  862. Wait_For_Key:                             ;Force user to notice error
  863.         PUSH    BP                        ;Save the only needed register
  864. ; Produce a beep to alert the user:  (use  BIOS TTY func to write an ASCII BELL)
  865.         MOV     AX,0E07h                  ;BIOS func (0Eh) to write (07H) beep
  866.         XOR     BH,BH                     ;Select page zero for output
  867.         INT     10h                       ;BIOS video function (0Eh=write char)
  868.  
  869. ;Find out what attribute is being used for display
  870.         MOV     AH,08h                    ;read attrib + char function
  871.         INT     10h                       ;Call BIOS
  872.         PUSH    AX                        ;Save AH=attribute byte
  873.  
  874. ;Find out what line the cursor is on
  875.         MOV     AH,03h                    ;Read cursor position function
  876.         INT     10h                       ;BIOS video services
  877.         PUSH    DX                        ;DH contains row (line #) Save it!
  878.  
  879. ; Position cursor to current line + column 28: (TO BIOS  row 27)
  880.         MOV     AH,02                     ;BIOS int 10h set cursor position func
  881.         XOR     BH,BH                     ;Set page to zero
  882.                                           ;DH contains current row
  883.         MOV     DL,1Bh                    ;Set cusor current row and col 27
  884.         INT     10h                       ;BIOS video services
  885.  
  886. ; Put -Hit any key- message out with inverse video attribute type on
  887. ;       XOR     BH,BH                     ;Set page to zero  (BH is still 0)
  888.         MOV     BL,0F0h                   ;Inverse video attribute
  889.         MOV     CX,1                      ;Character count
  890.         MOV     SI,offset Hit_Key_Msg     ;The hit-any-key message
  891. Display_next_video_char:
  892.         MOV     AH,09h                    ;BIOS int 10h write attrib + char func
  893.         LODSB                             ;Get next character for output
  894.         PUSH    SI                        ;Save SI (int 10h may corrupt it)
  895.         INT     10h                       ;Put character and attribute out
  896.         INC     DX                        ;Advance cursor position
  897.         MOV     AH,02                     ;Adv cursor function
  898.         INT     10h                       ;   advance the cursor (BIOS)
  899.         POP     SI                        ;Restore saved SI
  900.         CMP     SI,offset Hit_key_Msg_end ;are we at end of message?
  901.         JB      Display_next_video_char   ;  If not get next char for display
  902.                                           ;  Else, wait for key press by user
  903. ; Wait for user to hit any key
  904.         XOR     AX,AX
  905.         INT     16h                       ;Wait for user to hit a key
  906.  
  907. ; Erase HIT ANY KEY message
  908.         POP     DX                        ;DH=current line number
  909.         POP     BX                        ;BH=user's screen attribute
  910.         MOV     AH,06h                    ;INIT window function
  911.         XOR     AL,AL                     ;Zero AL to clear window
  912.         MOV     CH,DH                     ;Current row (y coor upr lft)
  913.         MOV     CL,00                     ;Start in first char position
  914.         MOV     DL,79                     ;Last char pos - blank entire line
  915.         INT     10h                       ;Blank out line
  916.  
  917. ; Position cursor to start of blanked line
  918.         MOV     AH,02                     ;BIOS int 10h set cursor position func
  919.         XOR     DL,DL                     ;DH=cur line, DL=0: first char pos
  920.         XOR     BX,BX                     ;Use video page zero
  921.         INT     10h                       ;BIOS video services
  922.         POP     BP
  923.         RET                               ;Return to caller
  924.  
  925.  
  926. ; --------------------------------------------------;
  927. ; Initialization DATA STORAGE                       ;
  928. ; --------------------------------------------------;
  929. Root_dir      DB  '\'                        ;Zero terminated root dir string
  930. Zero_Byte     DB  0                          ;This must immed. follow Root_Dir
  931. File_Attrib   DW  0007h                      ;File attribute (RO, hidden + sys)
  932. File2_start   DW  0007h                      ;File attribute (RO, hidden + sys)
  933. New_Drive     DB  0                          ;Drive to change to in filespec1
  934. Start_MSG     DB  CR,LF,"CHKFILEC 1.0 ",BOX," PCDATA TOOLKIT (c) 1990"
  935.               DB  " Ziff Communications Co.",CR,LF
  936.               DB  "PC Magazine ",BOX," Wolfgang Stiller - Checking: "
  937. SM_End        LABEL  BYTE     ;End of the Start message
  938. Bad_Path_MSG  DB  'Invalid path/drive on filespec1.',CR,LF,'$'
  939. Bad_Parm_MSG  DB  'Unrecognized parameter detected.',cr,lf,lf,'$'
  940. Syntax_Msg    DB  "CHKFILEC 1.0 ",BOX," PCDATA TOOLKIT Copyright (c) 1990"
  941.               DB  " Ziff Communications Co.",CR,LF
  942.               DB  "PC Magazine ",BOX," Wolfgang Stiller",CR,LF,CR,LF
  943.               DB  'CHKFILEC will read all files which match the specified file '
  944.               DB  'name, reporting',CR,LF
  945.               DB  'two check values, plus DOS file size, date and time. This'
  946.               DB  ' information',CR,LF
  947.               DB  'is written in compressed, self checking form to a separate'
  948.               DB  ' report file which',CR,LF
  949.               DB  'can be used by CFcompC to validate file integrity.'
  950.               DB   CR,LF,LF
  951.               DB  'Syntax is: CHKFILEC filespec1 filespec2 [/D] [/I:zz] '
  952.               DB  '[/T] [/1] [/2]',CR,LF,LF
  953.               DB  '   filespec1 is the file specification for the file(s) to'
  954.               DB  ' check. Wild cards',CR,LF
  955.               DB  '             such as * or ? can be used as well as a drive'
  956.               DB  ' or directory.',CR,LF
  957.               DB  '   filespec2 is compressed report file of file check data.'
  958.               DB   CR,LF
  959.               DB  '   "/D"      Display directory entries as well as files.'
  960.               DB   CR,LF
  961.               DB  '   "/I:aa"   Ignore all files which begin with the 2 '
  962.               DB  'chars: aa.',CR,LF
  963.               DB  '   "/T"      Ignored if coded. Totals are always generated.'
  964.               DB   CR,LF
  965.               DB  '   "/1"      Utilize an alternate check value1 algorithm.'
  966.               DB   CR,LF
  967.               DB  '   "/2"      Utilize an alternate check value2 algorithm.'
  968.               DB   CR,LF,'$'
  969. Bad_file2_msg DB  '2nd file parameter (report file) is missing or bad.'
  970.               DB   CR,LF,'$'
  971. F2_Open_fail  DB  'Open failed for filespec2 (report file)'
  972.               DB   CR,LF,'$'
  973. No_CHK_MSG    DB  'No files were checked.'
  974.               DB   CR,LF,'$'
  975. Hit_Key_Msg   DB   '-Hit any key-'
  976. Hit_Key_MSG_end EQU  $
  977. User_file_spec  EQU  $                ;User specified file spec to check
  978. CSEG    EndS
  979.         END     CHKFILEC
  980.